/*
 * Function test of qtsm_lib_api using glib framework
 *
 * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
#include "gtest_qtsm_lib_comm.h"

#define PCR0_SIG_IDX                    8

static comm_req g_describe_pcr_reqs[] = {
    /* Index: The boundary value of index */
    {
        .reqmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_req_u = {
                .describe_pcr = {
                    .index = 0,
                    .data_len = PCR_MAX_LEN_384
                }
            }
        },
        .resmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_res_u = {
                .describe_pcr = {
                    .lock = 1,
                    .data_len = PCR_MAX_LEN_384,
                }
            }
        }
    },
    {
        .reqmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_req_u = {
                .describe_pcr = {
                    .index = 8,
                    .data_len = PCR_MAX_LEN_384
                }
            }
        },
        .resmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_res_u = {
                .describe_pcr = {
                    .lock = 1,
                    .data_len = PCR_MAX_LEN_384,
                }
            }
        }
    },
    {
        .reqmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_req_u = {
                .describe_pcr = {
                    .index = 31,
                    .data_len = PCR_MAX_LEN_384
                }
            }
        },
        .resmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_res_u = {
                .describe_pcr = {
                    .lock = 0,
                    .data_len = PCR_MAX_LEN_384,
                    .data = (uint8_t[PCR_MAX_LEN_384]){0}
                }
            }
        }
    },
    /* Index: Out of pcr index range */
    {
        .reqmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_req_u = {
                .describe_pcr = {
                    .index = 32,
                    .data_len = PCR_MAX_LEN_384
                }
            }
        },
        .resmsg = {
            .type = ERROR_CODE,
            .qtsm_message_res_u = {
                .error_num = INVALID_INDEX
            }
        }
    },
    /* data_len: > PCR_MAX_LEN_384 */
    {
        .reqmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_req_u = {
                .describe_pcr = {
                    .index = 2,
                    .data_len = PCR_MAX_LEN_384 + 1
                }
            }
        },
        .resmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_res_u = {
                .describe_pcr = {
                    .lock = 1,
                    .data_len = PCR_MAX_LEN_384,
                    .data = (uint8_t[PCR_MAX_LEN_384]){0}
                }
            }
        }
    },
    /* data_len: < PCR_MAX_LEN_384 */
    {
        .reqmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_req_u = {
                .describe_pcr = {
                    .index = 2,
                    .data_len = PCR_MAX_LEN_384 - 1
                }
            }
        },
        .resmsg = {
            .type = ERROR_CODE,
            .qtsm_message_res_u = {
                .error_num = BUFFER_TOO_SMALL
            }
        }
    },
    /* data_len: 0 means data is null */
    {
        .reqmsg = {
            .type = DESCRIBE_PCR,
            .qtsm_message_req_u = {
                .describe_pcr = {
                    .index = 2,
                    .data_len = 0
                }
            }
        },
        .resmsg = {
            .type = ERROR_CODE,
            .qtsm_message_res_u = {
                .error_num = INVALID_ARGUMENT
            }
        }
    }
};

void gtest_qtsm_describe_pcr(const void *qtsm_dev_fd)
{
    uint32_t index;
    uint32_t data_len;
    uint8_t *data = NULL;
    bool locked = false;
    int rc;
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(g_describe_pcr_reqs); i++) {
        /* malloc data to store pcr value */
        data_len = g_describe_pcr_reqs[i].reqmsg.qtsm_message_req_u.describe_pcr.data_len;
        if (data_len != 0) {
            data = g_malloc0(data_len);
            g_assert_nonnull(data);
        }

        /* test describe pcr interface */
        index = g_describe_pcr_reqs[i].reqmsg.qtsm_message_req_u.describe_pcr.index;

        rc = qtsm_describe_pcr(*(int *)qtsm_dev_fd, index, &locked, data, &data_len);

        if (g_describe_pcr_reqs[i].resmsg.type == ERROR_CODE) {
            /* check error code */
            g_assert_cmpint(rc, ==,
                g_describe_pcr_reqs[i].resmsg.qtsm_message_res_u.error_num);
        } else {
            /* check ret value */
            g_assert_cmpint(rc, ==, NO_ERROR);
            /* check pcr value */
            g_assert_cmpint(locked, ==,
                g_describe_pcr_reqs[i].resmsg.qtsm_message_res_u.describe_pcr.lock);
            g_assert_cmpint(data_len, ==,
                g_describe_pcr_reqs[i].resmsg.qtsm_message_res_u.describe_pcr.data_len);
            if (index != 0 && index != PCR0_SIG_IDX)
                g_assert_cmpmem(data, data_len,
                    g_describe_pcr_reqs[i].resmsg.qtsm_message_res_u.describe_pcr.data,
                    g_describe_pcr_reqs[i].resmsg.qtsm_message_res_u.describe_pcr.data_len);
        }

        g_free(data);
        data = NULL;
    }
}